-
Notifications
You must be signed in to change notification settings - Fork 11.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[consensus] Exclude low scoring ancestors in proposals with time based inclusion/exclusion #19605
base: main
Are you sure you want to change the base?
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
3 Skipped Deployments
|
65183ba
to
e33f913
Compare
57062c2
to
c209697
Compare
c209697
to
59ae4a5
Compare
59ae4a5
to
628d399
Compare
5f24a49
to
f3dcbaa
Compare
f3dcbaa
to
58bd29c
Compare
## Description To be used in smart ancestor selection [PR#19605](#19605) --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API:
58bd29c
to
361d90d
Compare
361d90d
to
ee3bf25
Compare
ee3bf25
to
cbf0789
Compare
match ancestor_info.state { | ||
// Check conditions to switch to EXCLUDE state | ||
AncestorState::Include => { | ||
if propagation_score <= low_score_threshold { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered / tried exclusion based on the gap between a peer's low and high quorum rounds? Maybe we can leave a TODO here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did consider this but thought excluding based on the quality (votes) of blocks distributed was also important but I can give this a try. Do you have a sense for a good threshold between low and high quorum rounds. I believe it should not be more than 1 round in the healthy cases but wanted to confirm. Maybe something like 5-10 rounds is a good threshold for exclusion?
consensus/core/src/metrics.rs
Outdated
).unwrap(), | ||
included_excluded_proposal_ancestors_count_by_authority: register_int_counter_vec_with_registry!( | ||
"included_excluded_proposal_ancestors_count_by_authority", | ||
"Total number of included excluded ancestors per authority during proposal. Either weak or strong type", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"included excluded" , this could be a bit confusing (at least to me). Maybe something like Total number of ancestors per authority with 'excluded' status that got included in proposal. Either weak or strong type.
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah its a little confusing, changed the description but left the metric name as is. If you have a batter name idea for the metric let me know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay in reviewing.
consensus/core/src/dag_state.rs
Outdated
@@ -919,8 +968,8 @@ impl DagState { | |||
self.scoring_subdag.is_empty() | |||
} | |||
|
|||
pub(crate) fn calculate_scoring_subdag_scores(&self) -> ReputationScores { | |||
self.scoring_subdag.calculate_scores() | |||
pub(crate) fn calculate_scoring_subdag_distributed_vote_scores(&self) -> ReputationScores { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we have done the protocol upgrade, is it still worth renaming?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I renamed it back to calculate_scoring_subdag_scores
but will go in and cleanup more of the leader scoring code now that we have done the protocol upgrade in a separate PR
self.context.metrics.node_metrics.smart_selection_wait.inc(); | ||
debug!("Only found {} stake of good ancestors to include for round {clock_round}, will wait for more.", parent_round_quorum.stake()); | ||
return vec![]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it ok to continue when not smart_select
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, when we are not in smart_select
mode which means we are in the force=true
try_propose
mode we will just fall back to essentially the old behavior where we will include enough "EXCLUDE" ancestors until we have reached a quorum for the parent round.
a57e9df
to
0ec03ed
Compare
0ec03ed
to
9967b40
Compare
Add time based inclusion logic
9967b40
to
40f4a4a
Compare
40f4a4a
to
e0d5607
Compare
// Inclusion threshold is based on network quorum round | ||
const INCLUSION_THRESHOLD_PERCENTAGE: u64 = 90; | ||
|
||
pub(crate) fn new(context: Arc<Context>, propagation_scores: ReputationScores) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to pass in propagation_scores
, instead of calling set_propagation_scores()
?
// If round prober has not run yet and we don't have network quorum round, | ||
// it is okay because network_low_quorum_round will be zero and we will | ||
// include all ancestors until we get more information. | ||
let network_low_quorum_round = self.calculate_network_low_quorum_round(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we discussed, it may be safer to use a high quorum round instead for network round.
@@ -370,6 +384,43 @@ impl Core { | |||
} | |||
} | |||
|
|||
// TODO: produce the block for the clock_round. As the threshold clock can advance many rounds at once (ex | |||
// because we synchronized a bulk of blocks) we can decide here whether we want to produce blocks per round |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we are reasonably sure we only want to build the latest blocks. Earlier blocks do not contribute to voting, and they can be close to GC or voting limit.
Release notes
Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required.
For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates.